
package com.yimixian.app.util;

import android.annotation.TargetApi;
import android.os.Build;
import android.view.View;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;

public class GlobalLayoutUtils {

    /**
     * Execute the runnable on the next layout
     * 
     * @param view
     * @param runnable
     */
    public static void runAfterLayout(final View view, final Runnable runnable) {
        OnGlobalLayoutListener listener = new OnGlobalLayoutListener() {
            @Override
            @TargetApi(16)
            public void onGlobalLayout() {
                runnable.run();
                removeListener(view, this);
            }
        };
        addListener(view, listener);
    }

    /**
     * Execute the runnable once the view has a nonzero width and a nonzero
     * height
     * 
     * @param view
     * @param runnable
     */
    public static OnGlobalLayoutListener runAfterSizedLayout(
            final View view,
            final Runnable runnable) {
        if (view.getWidth() > 0 && view.getHeight() > 0) {
            runnable.run();
            return null;
        }

        return GlobalLayoutUtils.runAfterSizedLayoutOfViewHierarchy(view, runnable);
    }

    /**
     * Execute the runnable once the entire view tree has been laid out.
     * 
     * @param view
     * @param runnable
     */
    public static OnGlobalLayoutListener runAfterSizedLayoutOfViewHierarchy(
            final View view,
            final Runnable runnable) {
        OnGlobalLayoutListener listener = new OnGlobalLayoutListener() {
            @Override
            @TargetApi(16)
            public void onGlobalLayout() {
                if (view.getWidth() > 0 && view.getHeight() > 0) {
                    runnable.run();
                    removeListener(view, this);
                } else {
                    // If view is not wired into layout, remove listener rather
                    // than leaking memory
                    if (!CustomViewUtils.viewIsWiredIn(view)) {
                        removeListener(view, this);
                    }
                }
            }
        };
        addListener(view, listener);
        return listener;
    }

    /**
     * Execute the runnable on the next layout where the view has either a
     * different width or a different height
     * 
     * @param view
     * @param runnable
     */
    public static void runAfterResizeLayout(final View view, final Runnable runnable) {
        final int originalWidth = view.getWidth();
        final int originalHeight = view.getHeight();

        OnGlobalLayoutListener listener = new OnGlobalLayoutListener() {
            @Override
            @TargetApi(16)
            public void onGlobalLayout() {
                if (originalWidth != view.getWidth() || originalHeight != view.getHeight()) {
                    runnable.run();
                    removeListener(view, this);
                }
            }
        };
        addListener(view, listener);
    }

    public static void addListener(
            final View view,
            final OnGlobalLayoutListener listener) {
        if (view == null) {
            return;
        }
        view.getViewTreeObserver().addOnGlobalLayoutListener(listener);
    }

    public static void removeListener(
            final View view,
            final OnGlobalLayoutListener listener) {
        // Remove the layout listener
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
            view.getViewTreeObserver().removeOnGlobalLayoutListener(listener);
        } else {
            view.getViewTreeObserver().removeGlobalOnLayoutListener(listener);
        }
    }
}
